package org.example;

/*import io.netty5.bootstrap.ServerBootstrap;
import io.netty5.channel.Channel;
import io.netty5.channel.ChannelInitializer;
import io.netty5.channel.EventLoopGroup;
import io.netty5.channel.MultithreadEventLoopGroup;
import io.netty5.channel.nio.NioHandler;
import io.netty5.channel.socket.SocketChannel;
import io.netty5.channel.socket.nio.NioServerSocketChannel;
import io.netty5.handler.codec.http.HttpObjectAggregator;
import io.netty5.handler.codec.http.HttpServerCodec;
import io.netty5.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty5.handler.logging.LogLevel;
import io.netty5.handler.logging.LoggingHandler;
import io.netty5.handler.stream.ChunkedWriteHandler;
import org.example.handler.StompWebSocketFrameHandler;*/

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.codec.stomp.StompSubframeDecoder;
import io.netty.handler.codec.stomp.StompSubframeEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.example.handler.HttpStompHandler;
import org.example.handler.Netty4StompWebSocketFrameHandler;

import java.net.InetSocketAddress;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Hello world!
 *
 */
public class App 
{

    private final int port;

    public App(int port) {
        this.port = port;
    }

    /*public void start() throws Exception {
        //EventLoopGroup group = new MultithreadEventLoopGroup(0, NioHandler.newFactory());

        // 使用 MultithreadEventLoopGroup 并传入虚拟线程执行器
        // 创建虚拟线程执行器
        Executor virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
        EventLoopGroup group = new MultithreadEventLoopGroup(0, virtualThreadExecutor, NioHandler.newFactory());

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(group)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler()) // 日志处理
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            // 添加其他 Channel 处理器
                            ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
                            ch.pipeline().addLast(new HttpServerCodec());
                            ch.pipeline().addLast(new HttpObjectAggregator<>(64 * 1024)); // 聚合 HTTP 消息
                            ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws", "stomp", true));
                            ch.pipeline().addLast(new ChunkedWriteHandler());
                            ch.pipeline().addLast(new StompSubframeDecoder());
                            ch.pipeline().addLast(new StompSubframeEncoder());
                            ch.pipeline().addLast(new StompWebSocketFrameHandler());
                        }
                    });

            // 绑定并开始监听，使用 Netty 5.x 的 asStage().sync()
            Channel serverChannel = bootstrap.bind(new InetSocketAddress(port)).asStage().sync().getNow();

            // 使用addListener手动关闭Channel
            serverChannel.closeFuture().asStage().thenRun(() -> {
                System.out.println("Server channel is closed.");
                serverChannel.close();
            });

        } finally {
            group.shutdownGracefully();
        }
    }*/

    public void run() throws InterruptedException {
        /*EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();*/
        Executor virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
        EventLoopGroup bossGroup = new NioEventLoopGroup(1, virtualThreadExecutor); // 只用一个boss线程
        EventLoopGroup workerGroup = new NioEventLoopGroup(0, virtualThreadExecutor); // worker线程使用虚拟线程池
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>()  {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            /*ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
                            ch.pipeline().addLast(new HttpServerCodec());
                            ch.pipeline().addLast(new HttpObjectAggregator(65536));
                            ch.pipeline().addLast(new WebSocketServerProtocolHandler("/websocket",true));
                            ch.pipeline().addLast(new ChunkedWriteHandler());
                            ch.pipeline().addLast(new StompSubframeDecoder());
                            ch.pipeline().addLast(new StompSubframeEncoder());
                            ch.pipeline().addLast(new Netty4StompWebSocketFrameHandler()); // 自定义处理器*/

                            // 添加 HTTP 和 WebSocket 支持的处理器链
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new HttpServerCodec());  // HTTP 编码解码
                            p.addLast(new HttpObjectAggregator(65536)); // 将 HTTP 聚合为 FullHttpRequest/FullHttpResponse
                            p.addLast(new ChunkedWriteHandler()); // 处理分块写操作
                            p.addLast(new WebSocketServerCompressionHandler()); // WebSocket 压缩支持
                            p.addLast(new WebSocketServerProtocolHandler("/ws", null, true)); // WebSocket 协议处理

                            // 自定义的 HTTP 和 WebSocket 请求处理器
                            p.addLast(new HttpStompHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync(); // 等待服务端关闭
            //f.channel().closeFuture().await();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main( String[] args )
    {
        /*try {
            new App(8080).start();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }*/
        try {
            new App(8080).run();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println( "Hello World!" );
    }
}
